import json
from django.http import JsonResponse
from django.contrib.auth import authenticate, login
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework_jwt.settings import api_settings
from login.models import MyUser, Group
from datetime import datetime
import xlrd


static_file_path = 'static/files/'


def user_login(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': '请求参数错误'})
    username = json_dict.get('username', None)
    password = json_dict.get('password', None)

    if username is None or password is None:
        return JsonResponse({'code': 500, 'message': '请求参数错误'})

    is_login = authenticate(request, username=username, password=password)
    if is_login is None:
        return JsonResponse({'code': 500, 'message': '账号或密码错误'})

    user = MyUser.objects.get(username=username)
    if user.group.EndAt < datetime.now() or datetime.now() < user.group.StartedAt:
        return JsonResponse({'code': 500, 'message': '账号不在活跃期'})
    tmp_dict = dict()
    tmp_dict['name'] = user.nickname
    tmp_dict['email'] = user.email
    tmp_dict['character'] = 'normal_user'
    tmp_dict['lastloginTime'] = str(user.last_login)
    tmp_dict['account'] = user.username
    tmp_dict['key'] = user.id

    login(request, is_login)

    jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
    jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
    payload = jwt_payload_handler(is_login)
    token = jwt_encode_handler(payload)

    return JsonResponse(
        {
            'code': 200,
            'message': '登录成功',
            'data': {'token': token, 'info': tmp_dict}
        }
    )


# 下面的3个装饰器全部来自from引用，相当与给接口增加了用户权限校验和token校验
@api_view(['POST'])
@permission_classes((IsAuthenticated,))
@authentication_classes((JSONWebTokenAuthentication,))
def get_info(request):
    data = 'test for authentication'
    return JsonResponse(
        {
            'code': 200,
            'message': '请求成功',
            'data': data
        }
    )


def register(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': '请求参数错误'})
    username = json_dict.get('username', None)
    password = json_dict.get('password', None)
    email = json_dict.get('email', None)
    if username and password and email:
        queryset = MyUser.objects.filter(username=username)
        if not queryset.exists():
            user = MyUser.objects.create_user(username, email, password)
            if user:
                user.save()
                return JsonResponse(
                    {
                        'code': 200,
                        'message': '请求成功',
                        'data': '用户创建成功',
                    }
                )
            else:
                return JsonResponse(
                    {
                        'code': 403,
                        'message': '用户创建失败',
                    }
                )
        else:
            return JsonResponse(
                {
                    'code': 403,
                    'message': '用户已经存在',
                }
            )
    else:
        return JsonResponse(
            {
                'code': 500,
                'message': '请求参数错误'
            }
        )


@api_view(['POST'])
@permission_classes((IsAuthenticated,))
@authentication_classes((JSONWebTokenAuthentication,))
def modify_password(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': '请求参数错误'})
    username = json_dict.get('username', None)
    password = json_dict.get('password', None)
    re_password = json_dict.get('re_password', None)
    if username is None or password is None or re_password is None:
        return JsonResponse({'code': 500, 'message': '请求参数错误'})

    if password != re_password:
        return JsonResponse({'code': 500, 'message': '两次密码不一致'})
    user = MyUser.objects.get(username=username)
    user.set_password(password)
    user.save()

    return JsonResponse(
        {
            'code': 200,
            'message': '请求成功',
            'data': '密码修改成功',
        }
    )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def query_user(request):
    users = MyUser.objects.filter(is_superuser=0)
    data = list()
    for user in users:
        tmp_user = MyUser.objects.get(username=user)
        tmp_dict = dict()
        tmp_dict['name'] = tmp_user.nickname
        tmp_dict['email'] = tmp_user.email
        tmp_dict['character'] = 'normal_user'
        tmp_dict['lastloginTime'] = str(tmp_user.last_login)
        tmp_dict['account'] = user.username
        tmp_dict['key'] = user.id
        tmp_dict['nickclassnumber'] = user.nickclassnumber
        data.append(tmp_dict)
    return JsonResponse(
        {
            'code': 200,
            'message': '请求成功',
            'data': data,
        }
    )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def query_superuser(request):
    users = MyUser.objects.filter(is_superuser=1)
    data = list()
    for user in users:
        tmp_user = MyUser.objects.get(username=user)
        tmp_dict = dict()
        tmp_dict['name'] = tmp_user.nickname
        tmp_dict['nick_class'] = tmp_user.nickclassnumber
        tmp_dict['email'] = tmp_user.email
        tmp_dict['character'] = 'super_user'
        tmp_dict['lastloginTime'] = str(tmp_user.last_login)
        tmp_dict['account'] = user.username
        tmp_dict['key'] = user.id
        data.append(tmp_dict)
    return JsonResponse(
        {
            'code': 200,
            'message': '请求成功',
            'data': data,
        }
    )


@api_view(['POST'])
@permission_classes((IsAuthenticated, ))
@authentication_classes((JSONWebTokenAuthentication,))
def modify_info(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': 'json格式错误'})
    username = json_dict.get('username', None)
    email = json_dict.get('email', None)
    nickname = json_dict.get('name', None)

    if username is None:
        return JsonResponse({'code': 500, 'message': '请求参数错误'})

    try:
        user = MyUser.objects.get(username=username)
        if user is None:
            return JsonResponse({'code': 500, 'message': '用户未找到'})
    except Exception:
        return JsonResponse({'code': 500, 'message': '用户未找到'})
    if email:
        user.email = email
        user.save()
    if nickname:
        user.nickname = nickname
        user.save()

    return JsonResponse(
        {
            'code': 200,
            'message': '操作成功'
        }
    )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def add_group(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': '请求参数错误'})
    name = json_dict.get('name', None)
    start_time = json_dict.get('start_time', None)
    end_time = json_dict.get('end_time', None)
    number = json_dict.get('number', None)
    if start_time and end_time and name:
        try:
            start = datetime.strptime(start_time, '%Y-%m-%d')
            end = datetime.strptime(end_time, '%Y-%m-%d')
            if number:
                p = Group.objects.create(is_delete=False, StartedAt=start,
                                         EndAt=end, name=name, number=int(number))
            else:
                p = Group.objects.create(is_delete=False, StartedAt=start,
                                         EndAt=end, name=name)
            p.save()
            return JsonResponse(
                {
                    'code': 200,
                    'message': '请求成功'
                }
            )
        except Exception:
            return JsonResponse(
                {
                    'code': 500,
                    'message': '请求参数错误'
                }
            )
    else:
        return JsonResponse(
            {
                'code': 500,
                'message': '请求参数错误'
            }
        )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def modify_group(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': '请求参数错误'})
    group_number = json_dict.get('number', None)
    name = json_dict.get('name', None)
    start_time = json_dict.get('start_time', None)
    end_time = json_dict.get('end_time', None)
    if not name:
        return JsonResponse(
            {
                'code': 500,
                'message': '请求参数错误'
            }
        )
    try:
        group = Group.objects.get(name=name)
        if group_number:
            group.group_number = group_number
            group.save()
        if start_time:
            group.StartedAt = datetime.strptime(start_time, '%Y-%m-%d')
            group.save()
        if end_time:
            group.EndAt = datetime.strptime(end_time, '%Y-%m-%d')
            group.save()
        return JsonResponse(
            {
                'code': 200,
                'message': '修改成功'
            }
        )
    except:
        return JsonResponse(
            {
                'code': 500,
                'message': '没有此班级'
            }
        )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def delete_group(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': '请求参数错误'})
    group_name = json_dict.get('name', None)
    if not group_name:
        return JsonResponse(
            {
                'code': 500,
                'message': '请求参数错误'
            }
        )
    try:
        Group.objects.filter(name=group_name).delete()
        return JsonResponse(
            {
                'code': 200,
                'message': '修改成功'
            }
        )
    except:
        return JsonResponse(
            {
                'code': 500,
                'message': '没有此班级'
            }
        )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def query_group(request):
    groups = Group.objects.filter(is_delete=False)
    data = list()
    for group in groups:
        tmp_dict = dict()
        tmp_dict['name'] = group.name
        tmp_dict['number'] = group.number
        tmp_dict['time'] = str(group.StartedAt) + '#' + str(group.EndAt)
        tmp_dict['student_number'] = len(group.user_group.all())
        tmp_dict['key'] = group.id
        data.append(tmp_dict)
    return JsonResponse(
        {
            'code': 200,
            'message': '请求成功',
            'data': data,
        }
    )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def query_group_member(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': '请求参数错误'})
    groupname = json_dict.get('name', None)
    if not groupname:
        return JsonResponse({'code': 500, 'message': '未找到班级名称name'})
    users = MyUser.objects.filter(group__name=groupname)
    data = list()
    for user in users:
        tmp_dict = dict()
        tmp_dict['name'] = user.nickname
        tmp_dict['email'] = user.email
        if user.is_superuser == 1:
            tmp_dict['character'] = 'super_user'
        else:
            tmp_dict['character'] = 'normal_user'
        tmp_dict['lastloginTime'] = str(user.last_login)
        tmp_dict['account'] = user.username
        tmp_dict['key'] = user.id
        tmp_dict['nickclassnumber'] = user.nickclassnumber
        data.append(tmp_dict)
    return JsonResponse(
        {
            'code': 200,
            'message': '请求成功',
            'data': data,
        }
    )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def search_group_member(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': '请求参数错误'})
    groupname = json_dict.get('name', None)
    string = json_dict.get('string', None)
    if not groupname or not string:
        return JsonResponse({'code': 500, 'message': '未找到班级名称name或者搜索字符串string'})
    users = MyUser.objects.filter(group__name=groupname)
    data = list()
    for user in users:
        if string in user.username or string in user.nickname:
            tmp_dict = dict()
            tmp_dict['name'] = user.nickname
            tmp_dict['email'] = user.email
            if user.is_superuser == 1:
                tmp_dict['character'] = 'super_user'
            else:
                tmp_dict['character'] = 'normal_user'
            tmp_dict['lastloginTime'] = str(user.last_login)
            tmp_dict['account'] = user.username
            tmp_dict['key'] = user.id
            data.append(tmp_dict)
    return JsonResponse(
        {
            'code': 200,
            'message': '请求成功',
            'data': data,
        }
    )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def add_group_member(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': '请求参数错误'})
    groupname = json_dict.get('name', None)
    username = json_dict.get('username', None)
    nickname = json_dict.get('nickname', None)
    nickclassnumber = json_dict.get('nickclassnumber', None)
    email = json_dict.get('email', None)
    if not groupname or not username or not nickname:
        return JsonResponse({'code': 500, 'message': '必要参数缺失'})
    group = Group.objects.get(name=groupname)
    p = MyUser.objects.create(group=group, username=str(group.id) + '_' + username,
                              nickname=nickname, password=str(group.id) + '_' + username)
    if email:
        p.email = email
    if nickclassnumber:
        try:
            p.nickclassnumber = int(nickclassnumber)
        except Exception:
            pass
    p.save()

    return JsonResponse(
        {
            'code': 200,
            'message': '创建成功',
        }
    )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def delete_group_member(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': '请求参数错误'})
    username = json_dict.get('username', None)
    if not username:
        return JsonResponse({'code': 500, 'message': '必要参数缺失'})
    MyUser.objects.filter(username=username).delete()

    return JsonResponse(
        {
            'code': 200,
            'message': '删除成功',
        }
    )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def search_group(request):
    try:
        json_dict = json.loads(request.body)
    except Exception:
        return JsonResponse({'code': 500, 'message': '请求参数错误'})
    string = json_dict.get('string', None)
    if not string:
        return JsonResponse({'code': 500, 'message': '未找到搜索字符串string'})
    groups = Group.objects.filter()
    data = list()
    for group in groups:
        if string in group.name or string in str(group.number):
            tmp_dict = dict()
            tmp_dict['name'] = group.name
            tmp_dict['number'] = group.number
            tmp_dict['time'] = str(group.StartedAt) + '#' + str(group.EndAt)
            tmp_dict['student_number'] = len(group.user_group.all())
            tmp_dict['key'] = group.id
            data.append(tmp_dict)
    return JsonResponse(
        {
            'code': 200,
            'message': '请求成功',
            'data': data,
        }
    )


@api_view(['POST'])
@permission_classes((IsAuthenticated, IsAdminUser))
@authentication_classes((JSONWebTokenAuthentication,))
def add_group_members(request):
    name = request.POST.get("name")
    if not name:
        return JsonResponse({'code': 500, 'message': '请求参数错误'})
    groups = Group.objects.filter(name=name)
    if len(groups) == 0:
        return JsonResponse({'code': 500, 'message': '该分组未找到'})
    files = request.FILES.getlist("file")
    if len(files) == 0:
        return JsonResponse({'code': 500, 'message': '文件缺失'})
    f = files[0]
    group = groups[0]
    url = static_file_path + 'temp/' + name + '_' + f.name
    d = open(url, 'wb+')
    for chunk in f.chunks():
        d.write(chunk)
    d.close()
    data = xlrd.open_workbook(url)
    table = data.sheet_by_index(0)
    name_idx = -1
    number_idx = -1
    username_idx = -1
    for i in range(table.ncols):
        if table.cell(0, i).value == 'name':
            name_idx = i
        elif table.cell(0, i).value == 'nickclassnumber':
            number_idx = i
        elif table.cell(0, i).value == 'studentnumber':
            username_idx = i
    if name_idx == -1 or number_idx == -1 or username_idx == -1:
        return JsonResponse({'code': 500, 'message': '列名缺失'})
    for i in range(1, table.nrows):
        try:
            classnumber = str(int(table.cell(i, number_idx).value))
            nickname = str(table.cell(i, name_idx).value)
            username = str(int(table.cell(i, username_idx).value))
            p = MyUser.objects.create(group=group, username=str(group.id)+'_'+username,
                                      nickclassnumber=classnumber, password=str(group.id)+'_'+username,
                                      nickname=nickname)
            p.save()
        except Exception:
            print('数据不符和要求')

    return JsonResponse({'code': 200, 'message': '请求成功'})

